﻿using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using SimpleTool.SerialTool.SerialControl;
using SimpleTool.Server;
using System;
using System.Runtime.InteropServices;
using Serilog.Core;
using System.Windows.Shapes;
using System.Collections.Concurrent;
using SimpleTool.SerialTool;
using SimpleTool.Capacity;
using SimpleTool.ActivityUnit;
using System.Diagnostics;

namespace SimpleTool;

public static class Print
{
    [DllImport("kernel32.dll")]
    private static extern bool AllocConsole();

    private static bool _initialized = false;

    public static void WriteLine(params object[] message)
    {
        string infos = string.Empty;
        foreach (var info in message)
        {
            infos += info.ToString() + "   ";
        }
        if (!_initialized)
        {
            AllocConsole();
            _initialized = true;
        }
        Console.WriteLine(infos);
    }
}

/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application, IDisposable
{
    public IServiceProvider RetailSection { get; private set; }

    public App()
    {
        SeriLogInit();

        ServiceCollection Service = new();

        Service.AddSingleton<ISerialServer, SerialConfigServerManager>();

        Service.AddSingleton<IDatabaseServer, DatabaseServerManager>();

        Service.AddSingleton<IDirFileServer, DirFileServerManager>();

        Service.AddSingleton<IDenCryptoGraphic, DenCryptoGraphicManager>();

        Service.AddSingleton<IActivityDetetorAssist, ActivityDetetorAssistServer>();

        Service.AddSingleton<IPowerPlant, PowerPlantManeger>();

        Service.AddSingleton<MainViewModel>();

        Service.AddSingleton<SerialViewModel>();

        Service.AddSingleton<OverViewModel>();

        Service.AddSingleton<CapacityViewModel>();

        Service.AddSingleton<ActivityViewModel>();

        RetailSection = Service.BuildServiceProvider();

        System.Windows.Media.RenderOptions.ProcessRenderMode = System.Windows.Interop.RenderMode.SoftwareOnly;

        PresentationTraceSources.DataBindingSource.Switch.Level = SourceLevels.Warning;
    }

    protected override void OnExit(ExitEventArgs e)
    {
        Dispose();
        Log.CloseAndFlushAsync();
        base.OnExit(e);
    }

    /// <summary>
    /// avoid duplication release , add to the queue
    /// </summary>
    public void Dispose()
    {
        (RetailSection as IDisposable)?.Dispose();
        Log.CloseAndFlush();
        GC.SuppressFinalize(this);
    }

    protected static async void SeriLogInit()
    {
        string dir = "book";
        string suffix = "log";
        string flag = "snapshot_";
        string format = "yyyy-MM-dd HH_mm";
        string basedir = System.IO.Path.Combine("MyLog".CurrentDir(), dir);
        string logPath = System.IO.Path.Combine(basedir, flag + @DateTime.Now.ToString(@format) + "." + suffix);
        ConcurrentDictionary<int, string> pathMap = [];

        Print.WriteLine("...");

        var WaitAllCallBackTask = new TaskCompletionSource<bool>(); // await all callback be finish

        var dirfileServer = new DirFileServerManager();
        await dirfileServer.GetLocalFilesAsync(basedir, [flag], [suffix], (string file) =>
        {
            if (!string.IsNullOrEmpty(file))
            {
                foreach (var match in file.MatchTime(5))
                {
                    if (DateTime.TryParseExact(match, format, CultureInfo.InvariantCulture,
                        DateTimeStyles.None, out DateTime _time))
                    {
                        if (_time.Day == DateTime.Now.Day)
                        {
                            if (_time.Hour == DateTime.Now.Hour)
                            {
                                pathMap.TryAdd(_time.Minute, file);
                            }
                        }
                        else
                        {
                            File.Delete(file); // clear cache
                        }
                    }
                }
            }
            WaitAllCallBackTask.TrySetResult(true);
        });

        await WaitAllCallBackTask.Task;

        ICollection<int> minkey = pathMap.Keys;
        if (minkey.Count > 0)
        {
            if (pathMap.TryGetValue(minkey.Min(), out string? path)) logPath = path;
        }

        Log.Logger = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.Console().WriteTo.File
            (
            path: logPath,
            shared: true,
            rollingInterval: RollingInterval.Infinite,
            outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}"
            ).CreateLogger();

        Log.Logger.Debug("logger initi and dispose server success");

    }
}

